﻿Public Class Player
    Inherits Actor
    Dim PlayerRectangle As New Rectangle(200, 200, 75, 150)
    Dim BoundryBox As New RotatedRectangle(New Rectangle(57, 200, Map.TileSize, Map.TileSize), 0)
    Public Position As Vector2
    Dim srcBounds As New Rectangle(0, 0, 75, 150)

    Dim SpirteCheatSheet As New SpirteCheatSheet
    Dim Textr As Texture2D

    Dim HitBol As Boolean = False
    Dim ColBol As Boolean = False

    'Determines which frame is showing
    Dim direction As String = "stand"
    Public PlayerBearing As Double

    '~L~e~t~x~~be~~a~n~g~l~e~,~~y~~b~e~~m~a~g~n~a~t~u~d~e~.
    'Let x be FUCKING x, and y be y.
    Public Vector As Vector2 = New Vector2(0, 0)
    Const maxVector As Single = 16.0F
    Dim Speed As Single = 0

    Dim frameCount As Integer = 0
    'Counts which frame is currently in sourceBounds
    Dim delay As Integer = 5


    Dim mathsHel As MathHelper
    Dim CollisionSystem As New CollisionSystem

    Private Game As Game
    Private gamemap As Map

    ''' <summary>
    ''' Used to set up the Player class for operation, by parsing crucial data
    ''' </summary>
    ''' <param name="Game1">Passes the instance of the parent game class</param>
    ''' <param name="gamemap1">Passes the instance of Map in use</param>
    ''' <param name="textr2">Parses the Player Texture</param>
    Public Sub Intialise(Game1 As Game, gamemap1 As Map, textr2 As Texture2D)
        Game = Game1
        gamemap = gamemap1
        Textr = textr2
        BoundryBox.Origin = New Vector2(75, 150)
        Box2_Textr = Game.Content.Load(Of Texture2D)("Textures/blocks/orange")
    End Sub

    Dim msgbool As Boolean = False
    ''' <summary>
    ''' Starts the Player movement method, working off current direction. (e.g. Forward, backward?)
    ''' </summary>
    Private Sub PlayerMove()
        If frameCount Mod delay = 0 Then

            'Dim HitFlag As Boolean
            ''Box2 = New Rectangle(Box2_Pos.X + Box2.Width / 2, Box2_Pos.Y + Box2.Height / 2, 64, 64)
            'For Each Tile In gamemap.TileMap
            '    If BoundryBox.Intersects(Tile.Rectangle) And Tile.Type = "block" Then 'Or BoundryBox.Intersects(Box2) Then
            '        'Vector = CollisionSystem.RemoveNormalVelocity(Vector, PlayerBearing)
            '        Vector -= Vector2.Reflect(BoundryBox.m_Axis_smallest, BoundryBox.m_Axis_smallest)
            '        'Position -= BoundryBox.m_Axis_smallest

            '        'If msgbool = False Then
            '        'MsgBox(BoundryBox.m_Axis_smallest.ToString)
            '        'msgbool = True
            '        'End If

            '        ColBol = True
            '        HitBol = True
            '        Tile.State = "hit"
            '        HitFlag = True
            '    Else
            '        Tile.State = ""
            '    End If
            'Next

            'If HitFlag <> True Then
            '    ColBol = False
            '    HitBol = False
            'End If

            Select Case direction
                Case "stand"



                    ' PlayerRectangle.X += Vector.X '+= Math.Cos(PlayerBearing) * 1 * Vector.Y
                    ' PlayerRectangle.Y += Vector.Y '+= Math.Sin(PlayerBearing) * 1 * Vector.Y

                    Acceleration("stand")
                    Equalize(3)
                    'Check Frame, if > 8 (number of move animations), reset.
                    FrameCheck()
                    'Sets image to stand/idle
                    srcBounds = SpirteCheatSheet.TopDownDude_Move(1)

                    Exit Select
                Case "up"


                    Acceleration("up")

                    'PlayerRectangle.X += Vector.X '+= Math.Cos(PlayerBearing) * 1 * Vector.Y
                    ' PlayerRectangle.Y += Vector.Y '+= Math.Sin(PlayerBearing) * 1 * Vector.Y

                    'Check Frame, if > 8 (number of move animations), reset.
                    FrameCheck()
                    'Change image based on Frame selection.
                    srcBounds = SpirteCheatSheet.TopDownDude_Move(frameCount / (delay))

                Case "down"

                    Acceleration("down")

                    'PlayerRectangle.X += Vector.X '+= Math.Cos(PlayerBearing) * 1 * Vector.Y
                    'PlayerRectangle.Y += Vector.Y '+= Math.Sin(PlayerBearing) * 1 * Vector.Y

                    'Check Frame, if > 8 (number of move animations), reset.
                    FrameCheck()
                    'Change image based on Frame selection.
                    srcBounds = SpirteCheatSheet.TopDownDude_Move(frameCount / (delay))

            End Select

        End If

        frameCount += 1
        UpdatePlayerPostionAndAngle()

    End Sub

    ''' <summary>
    ''' Check Frame, if > 8 (number of move animations), reset.
    ''' </summary>
    Private Sub FrameCheck()
        If frameCount / delay >= 8 Then
            frameCount = 0
        End If
    End Sub

    ''' <summary>
    ''' Takes the type ("up, "down" etc.) and 
    ''' either speeds up or slows down the vector 
    ''' depending on whether the current speed is high
    ''' or low enough
    ''' </summary>
    ''' 
    Private Sub Acceleration(directionA As String)
        Select Case directionA
            Case "up"

                If Speed < maxVector Then
                    Speed += 1
                End If
                Dim Angle As Single = PlayerBearing
                Dim speedX As Single = Speed

                Dim Scale_x = Math.Cos(Angle)
                Dim Scale_y = Math.Sin(Angle)

                Dim Vel_x As Single = (speedX * Scale_x)
                Dim Vel_y As Single = (speedX * Scale_y)


                Vector = New Vector2(Vel_x, Vel_y)

                'Dim HitFlag As Boolean
                ''Box2 = New Rectangle(Box2_Pos.X + Box2.Width / 2, Box2_Pos.Y + Box2.Height / 2, 64, 64)
                'For Each Tile In gamemap.TileMap
                '    If BoundryBox.Intersects(Tile.Rectangle) And Tile.Type = "block" Then 'Or BoundryBox.Intersects(Box2) Then
                '        Vector = CollisionSystem.RemoveNormalVelocity(Vector, PlayerBearing)
                '        ColBol = True
                '        HitBol = True
                '        Tile.State = "hit"
                '        HitFlag = True
                '    Else
                '        Tile.State = ""
                '    End If
                'Next

                'If HitFlag <> True Then
                '    ColBol = False
                '    HitBol = False
                'End If

                Dim HitFlag As Boolean
                'Box2 = New Rectangle(Box2_Pos.X + Box2.Width / 2, Box2_Pos.Y + Box2.Height / 2, 64, 64)
                For Each Tile In gamemap.TileMap
                    If BoundryBox.Intersects(Tile.Rectangle) And Tile.Type = "block" Then 'Or BoundryBox.Intersects(Box2) Then
                        'Vector = CollisionSystem.RemoveNormalVelocity(Vector, PlayerBearing)
                        'Vector -= Vector2.Subtract(Vector, BoundryBox.m_Axis_smallest) '-= New Vector2(BoundryBox.m_Axis_Overlap, BoundryBox.m_Axis_Overlap) 'BoundryBox.m_Axis_smallest '+= Vector2.Reflect(BoundryBox.m_Axis_smallest, BoundryBox.m_Axis_smallest)
                        'Position -= BoundryBox.m_Axis_smallest

                        'If msgbool = False Then
                        'MsgBox(BoundryBox.m_Axis_smallest.ToString)
                        'msgbool = True
                        'End If

                        ColBol = True
                        HitBol = True
                        Tile.State = "hit"
                        HitFlag = True
                    Else
                        Tile.State = ""
                    End If
                Next

                If HitFlag <> True Then
                    ColBol = False
                    HitBol = False
                End If

                PlayerRectangle.X += Vector.X
                PlayerRectangle.Y += Vector.Y


            Case "stand"

                Dim Angle As Single = PlayerBearing
                Dim speedX As Single = Speed

                Dim Scale_x = Math.Cos(Angle)
                Dim Scale_y = Math.Sin(Angle)

                Dim Vel_x As Single = (speedX * Scale_x)
                Dim Vel_y As Single = (speedX * Scale_y)


                Vector = New Vector2(Vel_x, Vel_y)


                PlayerRectangle.X += Vector.X
                PlayerRectangle.Y += Vector.Y



            Case "down"
                If Vector.Y > 0 Then
                    Vector.Y -= 1
                End If
                If Vector.Y > -maxVector Then
                    Vector.Y -= 1
                End If

        End Select

    End Sub

    ''' <summary>
    ''' All the boiler work for the updating of
    ''' Angles, Positions (boundry and player)
    ''' </summary>
    Private Sub UpdatePlayerPostionAndAngle()

        Vector = New Vector2(PlayerBearing, Vector.Y)

        'Rectangle position is already taken from centre
        Position = New Vector2(PlayerRectangle.X, PlayerRectangle.Y)
        BoundryBox = New RotatedRectangle(New Rectangle(Position.X - BoundryBox.Width / 2, (Position.Y - BoundryBox.Height / 2), BoundryBox.Width, BoundryBox.Height), PlayerBearing) 'New Rectangle((Position.X - BoundryBox.Width / 2) * Math.Cos(PlayerBearing), (Position.Y - BoundryBox.Height / 2) * Math.Sin(PlayerBearing), BoundryBox.Width, BoundryBox.Height)
    End Sub

    ''' <summary>
    ''' Adds a parsed magnatude to the player angle
    ''' </summary>
    ''' <param name="sign">Does it "+" or "-" the angle?</param>
    ''' <param name="magnatude">How much does the angle change?</param>
    Private Sub IncreaseAngle(sign, magnatude)
        If sign = "+" Then
            PlayerBearing += mathsHel.ToRadians(magnatude)
        Else
            PlayerBearing -= mathsHel.ToRadians(magnatude)
        End If
        If Math.Abs(mathsHel.ToDegrees(PlayerBearing)) > 360 Then
            PlayerBearing = mathsHel.ToDegrees(0)
        End If
    End Sub


    ''' <summary>
    ''' Handles all player related inputs, and automates movement produces from there.
    ''' i.e. takes W/A/S/D and changes angles/directions/positions
    ''' </summary>
    Public Sub PlayerMovementHandler()

        If Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.D) = True Then
            'Right
            IncreaseAngle("+", 5)
        End If

        If Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.A) = True Then
            'Left
            IncreaseAngle("-", 5)
        End If

        If Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.W) = True Then
            'Up
            direction = "up"
        Else
            direction = "stand"
        End If

        If Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.S) = True Then
            'Down
            direction = "down"
        End If



        If Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Right) = True Then
            PlayerRectangle.X += 1
        End If

        If Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Left) = True Then
            PlayerRectangle.X -= 1
        End If

        If Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Up) = True Then
            PlayerRectangle.Y -= 1
        End If


        If Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Down) = True Then
            PlayerRectangle.Y += 1

        End If

        'Uses the above inputs to manipulate the player
        PlayerMove()
    End Sub


    Public Sub AI_MovementHandler(ByVal command As String)

        Select Case command
            Case "right"
                IncreaseAngle("+", 5)
            Case "left"


                IncreaseAngle("-", 5)
            Case "up"
                direction = "up"

                'direction = "stand"
            Case "down"

                direction = "down"

        End Select
        'If Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Right) = True Then
        '    PlayerRectangle.X += 1
        'End If

        'If Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Left) = True Then
        '    PlayerRectangle.X -= 1
        'End If

        'If Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Up) = True Then
        '    PlayerRectangle.Y -= 1
        'End If


        'If Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Down) = True Then
        '    PlayerRectangle.Y += 1

        'End If

        'Uses the above inputs to manipulate the player
        PlayerMove()
    End Sub


    ''' <summary>
    '''  Reduces Vector.Y's value for each interation passed ('i')
    ''' </summary>
    ''' <param name="i">How many interations to minus per cycle?</param>
    ''' <remarks></remarks>
    Private Sub Equalize(i As Integer)
        'Takes the Vector, and equalises the Vector to 0.
        For k As Integer = 0 To i - 1
            If Speed < 0.0F Then
                Speed += 1
            ElseIf Speed > 0.0F Then
                Speed -= 1
            End If
        Next
    End Sub


    Dim Box2 As Rectangle
    Dim Box2_Pos As New Vector2(200, 200)
    Dim Box2_Textr As Texture2D
    Dim Box2_TextureData As Color()
    ''' <summary>
    ''' Draws the player
    ''' </summary>
    ''' <param name="spriteBatch">The spritebatch which draws the player (use whatever you use for everything else)</param>
    ''' <param name="PlayerTexture">Texture to draw the player from (must be srpite map that corrseponds to SpriteCheatSheet)</param>
    ''' <remarks></remarks>
    Public Sub DrawPlayer(GraphicsDevice As GraphicsDevice, spriteBatch As SpriteBatch, PlayerTexture As Texture2D, Parsed_Light As Color)
        '                                                                          Mathshelper.toradians (offset the sprite by 90 as 90 is our true north!
        'spriteBatch.Draw(PlayerTexture, PlayerRectangle, srcBounds, Parsed_Light, PlayerBearing + MathHelper.ToRadians(90), New Vector2(75 / 2, 150 / 2), SpriteEffects.None, 0)

        Dim TEST As New CollisionSystem
        'TEST.DrawLine(GraphicsDevice, spriteBatch, 2, Color.White, New Vector2(Position.X - 10, Position.Y), New Vector2(Position.X - 10, Position.Y + BoundryBox.Width))
        'TEST.DrawLine(GraphicsDevice, spriteBatch, 2, Color.White, New Vector2(Position.X, Position.Y - 10), New Vector2(Position.X + BoundryBox.Width, Position.Y - 10))
        TEST.DrawLine(GraphicsDevice, spriteBatch, 2, Color.White, New Vector2(0, 0), New Vector2(Position.X + BoundryBox.Width / 4, Position.Y + BoundryBox.Width / 4))

        Dim GroundBlock As Texture2D = Game.Content.Load(Of Texture2D)("Textures/blocks/orange")
        If ColBol = True Then
            spriteBatch.Draw(PlayerTexture, PlayerRectangle, srcBounds, Color.PaleVioletRed, MathHelper.ToDegrees(MathHelper.WrapAngle(MathHelper.ToRadians(PlayerBearing))) + MathHelper.ToRadians(90), New Vector2(75 / 2, 150 / 2), SpriteEffects.None, 0)
            'spriteBatch.Draw(GroundBlock, New Rectangle(PlayerRectangle.X, PlayerRectangle.Y, Map.TileSize, Map.TileSize), srcBounds, Color.Red, PlayerBearing + MathHelper.ToRadians(90), New Vector2(75 / 2, 150 / 2), SpriteEffects.None, 0) 
        Else
            spriteBatch.Draw(PlayerTexture, PlayerRectangle, srcBounds, Parsed_Light, MathHelper.ToDegrees(MathHelper.WrapAngle(MathHelper.ToRadians(PlayerBearing))) + MathHelper.ToRadians(90), New Vector2(75 / 2, 150 / 2), SpriteEffects.None, 0)
            'spriteBatch.Draw(GroundBlock, New Rectangle(PlayerRectangle.X, PlayerRectangle.Y, Map.TileSize, Map.TileSize), srcBounds, Color.White, PlayerBearing + MathHelper.ToRadians(90), New Vector2(75 / 2, 150 / 2), SpriteEffects.None, 0) 
        End If


        'Dim TEST As New CollisionSystem
        'TEST.DrawLine(GraphicsDevice, spriteBatch, 2, Color.White, New Vector2(Position.X - 10, Position.Y), New Vector2(Position.X - 10, Position.Y + BoundryBox.Width))
        'TEST.DrawLine(GraphicsDevice, spriteBatch, 2, Color.White, New Vector2(Position.X, Position.Y - 10), New Vector2(Position.X + BoundryBox.Width, Position.Y - 10))
        ''TEST.DrawLine(GraphicsDevice, spriteBatch, 2, Color.White, New Vector2(Position.X, Position.Y + 10), New Vector2(Position.X - 10, Position.Y + BoundryBox.Width))
        'TEST.DrawLine(GraphicsDevice, spriteBatch, 2, Color.White, New Vector2(Position.X, Position.Y - 10), New Vector2(Position.X - 10, Position.Y + BoundryBox.Width))


        'Green box to test collision
        'spriteBatch.Draw(Box2_Textr, New Rectangle(Box2.X, Box2.Y, 64, 64), New Rectangle(0, 0, 64, 64), Color.Green)


    End Sub

    ''' <summary>
    ''' Draws Debug Text related to the player class.
    ''' </summary>
    ''' <param name="spriteBatch"></param>
    ''' <param name="SpriteText"></param>
    ''' <remarks></remarks>
    Public Sub DebugText(spriteBatch As SpriteBatch, SpriteText As SpriteFont, offset As Integer)
        offset *= 100
        spriteBatch.Begin()
        spriteBatch.DrawString(SpriteText, "Intersect?: " & ColBol & "    Does Hitbol?: " & HitBol.ToString, New Vector2(0, offset + 0), Color.FromNonPremultiplied(255 - offset * 50, 255 - offset * 50, 255 - offset * 50, 255))
        spriteBatch.DrawString(SpriteText, "BoundryBox: " & BoundryBox.CollisionRectangle.ToString, New Vector2(0, offset + 25), Color.FromNonPremultiplied(255 - offset * 50, 255 - offset * 50, 255 - offset * 50, 255))
        spriteBatch.DrawString(SpriteText, "Player Vector: Angle: " & mathsHel.ToDegrees(PlayerBearing) & " | Magnatude: " & Speed, New Vector2(0, offset + 50), Color.FromNonPremultiplied(255 - offset * 50, 255 - offset * 50, 255 - offset * 50, 255))
        spriteBatch.End()
    End Sub
End Class
